"""Implement interactions with smurfy.net."""

__author__  =  'Tailgunner'
__project__ =  'MW:O Drop Planner'


import logging
import urllib2
import re
import math   # This will import math module


from google.appengine.api        import memcache
from lib.Toolbox                 import WebTools

from BeautifulSoup               import BeautifulSoup

import HTMLParser
import BeautifulSoup
import Toolbox

logging.getLogger().setLevel(logging.DEBUG)

class Mechs():
    """Access to smurfys list of 'Mechs.""" 
    _list = None;
        
    @classmethod
    def list(cls, cached=True):
        """Returns smurfys list of 'Mechs, including local caching."""
                
        # check for cached version
        if (cls._list is None and cached):
            logging.info("Mechs.list: read local cache")
            cls._list = memcache.get("smurfy")
        
        # if nothing in cache, fetch the list and put
        # it in the cache
        if (cls._list is None):
            logging.info("Mechs.list: read remote cache")
            cls._list = Scraper.mechs()
            memcache.set("smurfy", cls._list, 24 * 60 * 60)
        
        return cls._list
    
    @classmethod
    def sorted_list(cls, cached=True):
        mechlist = cls.list(cached)
        mlist = []
        
        for key in sorted(mechlist.iterkeys()):
            mlist.append(key)
        
        return mlist

    @classmethod
    def list_grouped_by_class(cls):
        
        mechs    = cls.list()
        tonnages = {}
 
        for mech in mechs:
            tons  = mechs[mech]
            klass = ""
        
            if ( tons > 0 and tons < 40 ):
                klass = "Light"
            if ( tons > 35 and tons < 60 ):
                klass = "Medium"
            if ( tons > 55 and tons < 80 ):
                klass = "Heavy"
            if ( tons > 75 and tons < 110 ):
                klass = "Assault"
            
            hyphen = mech.find(u"\u208B")
            
            if ( hyphen > 0 and mech != u"X\u208B5" and mech != u"YEN\u208BLO\u208BWANG" ):
                model = mech[0:hyphen]
                variant = mech[hyphen+1:]
            else:
                klass = "Special"
                model = "HERO"
                variant = mech.replace(" ", "-")
            
            if ( not klass in tonnages ):
                tonnages[klass] = {}
                
            if ( not model in tonnages[klass] ):
                tonnages[klass][model] = []
            
            tonnages[klass][model].append(variant)
            tonnages[klass][model].sort()
            
        return tonnages
    
class Weapons():
    """Access to smurfys list of weapons."""
    #TODO: actually fetch from smurfy
    
    _list = None;
        
    @classmethod
    def list(cls, cached=True):
        """Returns smurfys list of weapons"""
        return Scraper.weapons()
    
class Modules():
    """Access to smurfys list of weapons.""" 
    #TODO: actually fetch from smurfy
    
    @classmethod
    def list(cls, cached=True):
        """Returns smurfys list of modules."""
        return Scraper.modules()
 

class Mech():
    """Access to smurfys list of weapons.""" 
    #TODO: actually fetch from smurfy
    
    @classmethod
    def fetch(cls, url, cached=True):
        """Returns smurfys list of modules."""
        return Scraper.mech(url)
            

class Scraper():
    """Scraper for smurfys HTML """
    
    @classmethod
    def roles(cls):
        """Scrapes the list of combat roles."""
        return [
            ["Scout",      "SC"],
            ["Support",    "SU"],
            ["Sniper",     "SN"],
            ["Brawler",    "B"],
            ["Skirmisher", "SK"],
            ["Tank",       "T"],
        ]
    
    @classmethod
    def mech(cls, mechurl):
        """Scrapes a 'Mech from smurfys HTML."""
    
        html = ""
        htmlparser = HTMLParser.HTMLParser()
        rgex_speed = re.compile('\d+\.\d kph')
            
        mech = { 'url': mechurl }
            
        try:
            html = urllib2.urlopen(mechurl).read();
            mech['html'] = str(html) 
            # mech.append(html)
        except urllib2.URLError, e:
            mech['html'] = "<" + e.reason + ">" 
            pass
            
        if html:
            soup = BeautifulSoup.BeautifulSoup(html)
 
            for h in soup.findAll('h4'):
                h.span.extract()
                h.small.extract()
                mech['mechtype'] = WebTools.utf8_ify(h.text)
                
            for s in soup.findAll('span'):
                if rgex_speed.search(s.text):
                    speed = s.text.replace(" kph", "")
                    #speed = int(math.ceil(float(int(float(speed)))/10))*10
                    #speed = float(int(float(speed)))/10
                    speed = int( math.ceil((float(int(float(speed)))/10)-0.5)*10)
                    mech['speed'] = speed
    
            mech['weapons']   = []
            mech['equipment'] = []
            #mech['li'] = []
            
            add_to    = ""
            
            for s in soup.findAll('li'):
                text = s.text

                if text.startswith("BAP:"):
                    mech['equipment'].append("BAP")
                
                if text.startswith("ECM:"):
                    mech['equipment'].append("ECM")
                
                if text.find("JumpJets") != -1:
                    mech['equipment'].append("Jumpjets")
                
                if text.find("Artemis") != -1:
                    mech['equipment'].append("Artemis")
                
                if text == "Armaments":
                    add_to = "w"
                    next
                elif text == "Ammunition":
                    add_to = "a"
                    next
                elif text == "Upgrades":
                    add_to = "e"
                    next
                elif add_to == "w":
                    #mech['li'].append(s.text);
                    
                    count  = s.span.text
                    s.span.extract
                    weapon = re.sub('\&nbsp;.+', "", s.text)
                    
                    weapon = re.sub('MACHINE GUN', "MG", weapon)
                    weapon = re.sub('(L|S)RM ', r"\1RM", weapon)
                    weapon = re.sub('PULSE LASER', "PLSR", weapon)
                    weapon = re.sub('ANTI-MISSILE SYSTEM', "AMS", weapon)
                    weapon = re.sub('LASER', "LSR", weapon)
                    weapon = re.sub('FLAMER', "FLM", weapon)
                    weapon = re.sub('LARGE|LRG', "L", weapon)
                    weapon = re.sub('MED(IUM)?', "M", weapon)
                    weapon = re.sub('SMALL|SML', "S", weapon)
                    weapon = re.sub(' RIFLE', "", weapon)
                    weapon = re.sub('ULTRA (.+)', r"\1 U", weapon)
                    weapon = re.sub('STREAK (.+)', r"\1 S", weapon)
                    weapon = re.sub('LB (\d+)-X AC', r"AC\1 X", weapon)
                    weapon = re.sub(" ", "-", weapon)
                    weapon = re.sub("/", "", weapon)
                    weapon = WebTools.utf8_ify(weapon)
                    for i in range(0,int(count)):
                        mech['weapons'].append(weapon)
      
        return mech
    
    @classmethod
    def mechs(cls):
        """Scrapes the list of 'Mechs from smurfys HTML."""
    
        htmlparser = HTMLParser.HTMLParser()
        
        mechlist = {}
        tonnage = 0
        
        try:
            html = urllib2.urlopen("http://mwo.smurfy-net.de/")
        except e:
            logging.error(e);
            
        if html:
            soup = BeautifulSoup.BeautifulSoup(html)
 
            for row in soup.findAll('tr'):
                if row.th:
                    tclass = row.th.get("class")
                    if tclass:
                        if u'mechs_family' == tclass:
                            tonnage = row.th.small.string
                            tonnage = int( re.sub("[\\(\\)]", "", tonnage) )
                
                if row.td:
                    link = row.td.a
                    if link:
                        href = link.get('href')
                        text =  WebTools.utf8_ify(htmlparser.unescape(str(link.string)))
                        
                        if href and re.match("/mechlab#i=", href):
                            if ( text.find("(C)") == -1 ) and ( text.find("(S)") == -1 ) and ( text.find("(F)") == -1 ):
                                if not text in mechlist:
                                    mechlist[text] = tonnage
                                    logging.info("ML " + text + "=" + str(tonnage)) 
                     
        return mechlist
    
    @classmethod
    def weapons(cls):
        """Scrapes the list of weapons from smurfys HTML."""
        #TODO: Actually fetch this from Smurfy
        
        return [
            [
                'Ballistic', [
                    ["mg", "MG"],
                    ["ac2", "AC2"],
                    ["ac5", "AC5"],
                    ["ac5u", WebTools.utf8_ify("AC5-U")],
                    ["ac10", "AC10"],
                    ["ac10x", WebTools.utf8_ify("AC10-X")],
                    ["ac20", "AC20"],
                    ["gauss", "Gauss"],
                ]
            ],
            [
                'Energy', [
                    ["slsr",   WebTools.utf8_ify("S-LSR")],
                    ["splsr",  WebTools.utf8_ify("S-PLSR")],
                    ["mlsr",   WebTools.utf8_ify("M-LSR")],
                    ["mplsr",  WebTools.utf8_ify("M-PLSR")],
                    ["llsr",   WebTools.utf8_ify("L-LSR")],
                    ["erllsr", WebTools.utf8_ify("ER-L-LSR")],
                    ["lplsr",  WebTools.utf8_ify("L-PLSR")],
                    ["ppc",    "PPC"],
                    ["erppc",  WebTools.utf8_ify("ER-PPC")],
                    ["flamer", "FLM"],
                ],
            ],
            [
                'Missiles', [
                    ["srm2", "SRM2"],
                    ["srm2s", WebTools.utf8_ify("SRM2-S")],
                    ["srm4", "SRM4"],
                    ["srm6", "SRM6"],
                    ["lrm5", "LRM5"],
                    ["lrm10", "LRM10"],
                    ["lrm15", "LRM15"],
                    ["lrm20", "LRM20"]
                ]
            ],
            [
                'Support', [
                    ["narc", "NARC"],
                    ["tag",  "TAG"],
                    ["ams",  "AMS"],
                ]
            ]
        ]

    @classmethod
    def modules(cls):
        """Scrapes the list of modules from smurfys HTML."""
        #TODO: Actually fetch this from Smurfy
        
        return [
            ["Vision", [
                ["azm", "Adv. Zoom"],
            ]],
            ["Targeting", [
                ["dec", "Target Decay"],
                ["360", "360 Degrees"],
            ]],
            ["Support", [
                ["cac", "Fast Cap"],
                ["aac", "Art. Acc."],
                ["aic", "Air. Acc."],
                ["hlc", "Hill climb"],
                ["agy", "Adv. Gyro"],
            ]],
            ["Sensor", [
                ["ssm", "Seismic"],
                ["tgi", "Info Gathering"],
                ["asr", "Adv. Sensor"],
            ]],
            ["Consumables", [
                ["col", "Coolshot"],
                ["uav", "UAV"],
                ["art", "Artillery Strike"],
                ["air", "Airstrike"],
            ]],
        ]